import chartFactory from '../index';

const chart = {};

chart.create = chartFactory;

chart.init = async function (opt) {
  this.create(opt);

  this.originInner = this.container.append('g')
    .attr('class', 'inner');
  this.originOuter = this.container.append('g')
    .attr('class', 'outer');
}
chart.update = function (_data) {

  this.data = _data || this.data;

  if (this.data == null)
    return;

  let parent = document.querySelector(this.config.target);
  this.width = parent.clientWidth - this.config.margin.left - this.config.margin.right;
  this.height = parent.clientHeight - this.config.margin.top - this.config.margin.bottom;

  this.originInner.attr('transform', `translate(${this.width / 2}, ${this.height / 2})`);
  this.originOuter.attr('transform', `translate(${this.width / 2}, ${this.height / 2})`);

  // 存储每个bar的总长度
  let width_per_bar_list = []

  this.data.bar.forEach(item => {
    width_per_bar_list.push(item["cover_num"]);
  });

  let innerRadius = 100,
    outerRadius = Math.min(this.width, this.height) / 2,
    xScaleOffset = Math.PI * 75 / 180;

  // 数据x方向值域范围定义
  this.x = d3
    .scaleBand()
    .domain(
      this.data.bar.map(function (d) {
        return d.bar_id;
      })
    )
    .range([xScaleOffset, 2 * Math.PI + xScaleOffset])
    .align(0);

  // 外圈数据y方向值域范围定义
  this.y1 = d3.scaleLinear().range([innerRadius, outerRadius]);

  // 内圈数据y方向值域范围定义
  this.y2 = d3.scaleLinear().range([innerRadius, innerRadius / 3]);

  // 类别与颜色值域范围定义:最内圈为定向层级1，颜色最深，映射为下标1 
  this.z = d3
    .scaleOrdinal()
    .range([
      "#691cc7", "#b07fed",
      "#1263e0", "#85b1f5",
      "#2a9332", "#6fd677",
      "#ff762b", "#ffceb3"
    ]);

  // 图例
  let zClasses = ["使用频次", "人口属性", "用户行为", "消费能力", "设备定向"];

  this.zLegend = d3
    .scaleOrdinal()
    .range([
      "#253494",
      "#691cc7",
      "#1263e0",
      "#2a9332",
      "#ff762b",
    ]);

  // 内圈数据模拟
  let innerdata = [{
    bar_id: 0,
    number: 20
  },
  {
    bar_id: 1,
    number: 5
  },
  {
    bar_id: 2,
    number: 10
  },
  {
    bar_id: 3,
    number: 20
  },
  {
    bar_id: 4,
    number: 4
  },
  {
    bar_id: 5,
    number: 7
  },
  {
    bar_id: 6,
    number: 31
  },
  {
    bar_id: 7,
    number: 40
  },
  {
    bar_id: 8,
    number: 14
  },
  {
    bar_id: 9,
    number: 9
  },
  {
    bar_id: 10,
    number: 18
  },
  {
    bar_id: 11,
    number: 6
  },
  {
    bar_id: 12,
    number: 11
  },
  {
    bar_id: 13,
    number: 9
  },
  {
    bar_id: 14,
    number: 5
  }
  ];

  // 外圈数据
  let outerdata = this.process(this.data, width_per_bar_list);

  // 外圈数据y方向定义域
  this.y1.domain([0, d3.max(width_per_bar_list)]);

  // 内圈数据y方向定义域
  this.y2.domain([
    0,
    d3.max(
      //  返回innerdata中number最大的数
      innerdata.map(d => {
        return d.number;
      })
    )
  ]);
  // 类别颜色定义域
  this.z.domain([
    "dx1",
    "dx1_none",
    "dx2",
    "dx2_none",
    "dx3",
    "dx3_none",
    "dx4",
    "dx4_none"
  ]);

  // 提示框
  this.tooltip = d3.select(this.config.target + ` .tooltip`);

  // 外圈数据绘制
  this.originOuter
    .selectAll("g")
    .data(outerdata)
    .enter()
    .append("g")
    .attr("class", function (d) {
      return d[0].id;
    })
    .selectAll("path")
    .data(function (d) {
      return d;
    })
    .enter()
    .append("path", d => {
      return `path_${d.data.bar_id}_${d.id}`
    })
    .attr("fill", (d, i) => {
      return this.z(d.z);
    })
    .attr("class", d => {
      return `path_${d.data.bar_id}_${d.id}`
    })
    .attr(
      "d",
      d3
        .arc()
        .innerRadius(d => {
          return this.y1(d[0]);
        })
        .outerRadius(d => {
          return this.y1(d[1]);
        })
        .startAngle(d => {
          return this.x(d.data.bar_id);
        })
        .endAngle(d => {
          return this.x(d.data.bar_id) + this.x.bandwidth();
        })
        .padAngle(0.01)
        .padRadius(innerRadius)
    )
    .attr("stroke", "#fff")
    .attr("stroke-width", 2)
    .style("opacity", function (d, i) {
      if (d.z.length > 3) return 0.3;
      else return 0.7;
    })
    .on("mouseover", (d, i) => {
      d3
        .select(`.path_${d.data.bar_id}_${d.id}`)
        .attr("fill", "#F15025")
        .attr("cursor", "pointer");
      this.tooltip
        .html("  定向：" + d.name + "  ")
        .style('visibility', 'visible')
        .style("left", d3.event.pageX + "px")
        .style("top", d3.event.pageY + 20 + "px")
        .style("opacity", 1.0);
    })
    .on("mousemove", (d) => {
      /* 鼠标移动时，更改样式 left 和 top 来改变提示框的位置 */

      this.tooltip
        .style("left", d3.event.pageX + "px")
        .style("top", d3.event.pageY + 20 + "px");
    })
    .on("mouseout", (d, i) => {
      d3
        .select(`.path_${d.data.bar_id}_${d.id}`)
        .attr("fill", () => {
          return this.z(d.z)
        })
        .attr("cursor", "pointer");
      /* 鼠标移出时，将透明度设定为0.0（完全透明）*/

      this.tooltip.style('visibility', 'hidden');
    });

  // 内圈数据绘制
  this.originInner
    .selectAll("path")
    .data(innerdata)
    .enter()
    .append("path")
    .attr("fill", "#253494")
    .attr("class", d => {
      return `path_${d.bar_id}`
    })
    .attr(
      "d",
      d3
        .arc()
        .innerRadius(d => {
          return this.y2(0);
        })
        .outerRadius(d => {
          return this.y2(d.number);
        })
        .startAngle(d => {
          return this.x(d.bar_id);
        })
        .endAngle(d => {
          return this.x(d.bar_id) + this.x.bandwidth();
        })
        .padAngle(0.01)
        .padRadius(innerRadius)
    )
    .on("mouseover", (d, i) => {
      d3
        .select(`.path_${d.bar_id}`)
        .attr("fill", "#F15025")
        .attr("cursor", "pointer");
      this.tooltip
        .html("数量：" + d.number + "  ")
        .style('visibility', 'visible')
        .style("left", d3.event.pageX + "px")
        .style("top", d3.event.pageY + 20 + "px");
    })
    .on("mousemove", (d) => {
      /* 鼠标移动时，更改样式 left 和 top 来改变提示框的位置 */

      this.tooltip
        .style("left", d3.event.pageX + "px")
        .style("top", d3.event.pageY + 20 + "px");
    })
    .on("mouseout", (d, i) => {
      d3
        .select(`.path_${d.bar_id}`)
        .attr("fill", "#253494")
        .attr("cursor", "pointer");
      /* 鼠标移出时，将透明度设定为0.0（完全透明）*/

      this.tooltip.style('visibility', 'hidden');
    });

  //yAxis and Mean
  // 坐标轴绘制
  this.yAxis = this.container
    .select(".outer")
    .append("g")
    .attr("text-anchor", "middle");

  let yTicksValues = d3.ticks(0, d3.max(width_per_bar_list), 2);

  // Mean value line
  // let yMeanTick = yAxis.append("g").datum([meanAccidents]);

  // yMeanTick
  //   .append("circle")
  //   .attr("fill", "none")
  //   .attr("stroke", "#C0625E")
  //   .attr("stroke-dasharray", "5 3")
  //   .attr("r", y);

  this.yTick = this.yAxis
    .selectAll("g")
    .data(yTicksValues)
    .enter()
    .append("g");

  // yTick
  //   .append("circle")
  //   .attr("fill", "none")
  //   .attr("stroke","gray")
  //   .attr("r", y1);

  // this.yTick
  //   .append("text")
  //   .attr("y", d => {
  //     return -this.y1(d);
  //   })
  //   .attr("dy", "0.35em")
  //   .attr("fill", "none")
  //   .attr("stroke", "#fff")
  //   .attr("stroke-width", 3)
  //   .text(this.y1.tickFormat(5, "s"));

  // this.yTick
  //   .append("text")
  //   .attr("y", d => {
  //     return -this.y1(d);
  //   })
  //   .attr("dy", "0.35em")
  //   .text(this.y1.tickFormat(5, "s"));

  // this.yAxis
  //   .append("text")
  //   .attr("y", d => {
  //     return -this.y1(yTicksValues.pop());
  //   })
  //   .attr("dy", "-2em")
  //   .text("value");

  // 绘制图例
  // this.legend = this.container.append("g")
  //   .attr('transform', `translate(${this.width - 10}, 10)`)
  //   .attr('class', 'legend')
  //   .selectAll("g")
  //   .data(zClasses)
  //   .enter()
  //   .append("g")
  //   .attr("transform", function (d, i) {
  //     return (
  //       "translate(-25," + (i - (zClasses.length - 1) / 2) * 25 + ")"
  //     );
  //   });

  // this.legend
  //   .append("circle")
  //   .attr("r", 5)
  //   .attr("fill", this.zLegend);

  // this.legend
  //   .append("text")
  //   .attr("x", 15)
  //   .attr("y", 0)
  //   .attr("dy", "0.2em")
  //   .text(function (d) {
  //     return d;
  //   });
}

chart.process = function (data, width_per_bar_list) {
  // data来自bar.json文件根据原始数据bar.json重新生成新结构的数据bar_data
  // 二级定向名称list
  let slice_column = [
    "dx11_flag",
    "dx12_flag",
    "dx13_flag",
    "dx14_flag",
    "dx21_flag",
    "dx22_flag",
    "dx23_flag",
    "dx24_flag",
    "dx25_flag",
    "dx26_flag",
    "dx31_flag",
    "dx32_flag",
    "dx41_flag",
    "dx42_flag"
  ];
  // stack_data为叠加数据集
  let stack_data = d3.stack().keys(slice_column)(data.bar);

  // bar_data为最终处理结果
  let bar_data = [];

  stack_data.forEach(item => {
    let item_bar = [];
    item.forEach((sub_item, index) => {
      let sub_item_bar = [
        item.index * width_per_bar_list[index] / 10,
        (item.index + 1) * width_per_bar_list[index] / 10
      ];
      sub_item_bar["data"] = sub_item.data;
      sub_item_bar["id"] = item.key.slice(0, 4);
      sub_item_bar["name"] = sub_item.data[item.key.slice(0, 5) + "name"];
      if (sub_item[0] == sub_item[1]) {
        sub_item_bar["z"] = item.key.slice(0, 3) + "_none";
      } else {
        sub_item_bar["z"] = item.key.slice(0, 3);
      }
      item_bar.push(sub_item_bar);
    });
    item_bar["key"] = item.key;
    item_bar["index"] = item.index;
    bar_data.push(item_bar);
  });

  return bar_data;
}

export default chart;